package com.ruoyi.app.schedule;

import com.ruoyi.app.business.project.ProjectBusiness;
import com.ruoyi.app.business.project.ProjectSettleBusiness;
import com.ruoyi.common.core.utils.LatchUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 作用：项目定时任务
 * </p>
 *
 * @author Zane
 * @since 2025-10-18 12:52
 */
@Slf4j
@Component
public class ProjectTask {

  @Resource
  private RedisService redisService;
  @Resource
  private ProjectBusiness projectBusiness;
  @Resource
  private ProjectSettleBusiness projectSettleBusiness;
  @Resource
  private Executor asyncExecutor;


  /**
   * 每分钟执行一次
   */
  @Scheduled(cron = "0 0/1 * * * ?")
  public void projectSchedule() {
    //定时任务执行
    final String key = "project:schedule:key:projectSchedule";
    if (redisService.setIfAbsent(key, "1", 60, TimeUnit.SECONDS)) {
      try {
        //开始执行
        LatchUtils.submitTask(asyncExecutor, () -> projectBusiness.toExecution());
        //延期通知
        LatchUtils.submitTask(asyncExecutor, () -> projectBusiness.notifyDelay());
        final boolean finishAll = LatchUtils.runAndWait(5, TimeUnit.MINUTES);
        if (!finishAll) {
          log.error("定时任务执行超过5分钟");
        }
      } catch (Exception e) {
        log.error(StringUtils.format("定时任务[{}]执行异常)",
            "ProjectTask.projectSchedule"), e);
      } finally {
        //释放锁
        redisService.deleteObject(key);
      }

    }
  }

  /**
   * 每天0,1点各执行一次
   */
  @Scheduled(cron = "0 0 9,15,21 * * ?")
  public void projectSettleSchedule() {
    //定时任务执行
    final String key = "project:schedule:key:projectSettleSchedule";
    if (redisService.setIfAbsent(key, "1", 60, TimeUnit.SECONDS)) {
      try {
        //开始执行
        projectSettleBusiness.settle();
      } catch (Exception e) {
        log.error(StringUtils.format("定时任务[{}]执行异常)",
            "ProjectTask.projectSettleSchedule"), e);
      } finally {
        //释放锁
        redisService.deleteObject(key);
      }

    }
  }
}
